package com.simple.util;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.simple.vo.WordRegion;
import com.simple.vo.WordRegionList;

public class WordRegionUtil {
	
	public static List<WordRegionList> handleOcr(String ocr, int width, int height){
		List<WordRegionList> returnList = new ArrayList<>();
		JSONObject ocrObject = JSON.parseObject(ocr);
		if(!ocrObject.getString("errorCode").equals("0")) {
			return returnList;
		}
		JSONArray regionArray = ocrObject.getJSONObject("Result").getJSONArray("regions");
		if (regionArray == null || regionArray.size() == 0) {
			return null;
		}
		int regionCount = regionArray.size();
		List<WordRegionList> allRegionList = new ArrayList<>();
		WordRegionList tempRegionList = null;
		for (int i = 0; i < regionCount; i++) { // 块
			JSONObject regionObj = (JSONObject)regionArray.get(i);
			String boundingBoxRegion = regionObj.getString("boundingBox");
			WordRegion region = new WordRegion(boundingBoxRegion);
			if(region.getWordHeight() > height/2 && region.getBottomY() > height*3/4) {
				if((region.getLeftX() > width*21/40 && region.getRightX() > (width-width/12)) || (region.getRightX() < width*19/40 && region.getLeftX() < width/12)) {
					continue;
				}
			}
			JSONArray lineArray = regionObj.getJSONArray("lines");
			if (lineArray == null || lineArray.size() == 0) {
				continue;
			}
			int lineCount = lineArray.size();
			for (int j = 0; j < lineCount; j++) { // 行
				JSONArray tmpArray = (JSONArray)lineArray.get(j);
				if (tmpArray == null || tmpArray.size() == 0) {
					continue;
				}
				for (int k = 0; k < tmpArray.size(); k++) {
					JSONObject obj = tmpArray.getJSONObject(k);
					String boundingBox = obj.getString("boundingBox");
					WordRegion wordRegion = new WordRegion(boundingBox);
					if(tempRegionList == null) {
						tempRegionList = new WordRegionList(wordRegion);
						allRegionList.add(tempRegionList);
					}
					else {
						boolean flag = judgetAdd(tempRegionList, wordRegion);
						if(!flag) {
							tempRegionList = new WordRegionList(wordRegion);
							allRegionList.add(tempRegionList);
						}
					}
				}
			}
		}
		Collections.sort(allRegionList, new Comparator<WordRegionList>() {

			@Override
			public int compare(WordRegionList arg0, WordRegionList arg1) {
				return arg0.getFirst().getLeftX() - arg1.getFirst().getLeftX();
			}
			
		});
		
		int count = 0;
		while(true) {
			boolean findFlag = false;
			while(count < allRegionList.size() - 1) {
				WordRegionList wordRegionList = allRegionList.get(count);
				for(int i = count+1; i < allRegionList.size(); i++) {
					WordRegionList wordRegionTemp = allRegionList.get(i);
					boolean add = judgetAddList(wordRegionList, wordRegionTemp);
					if(add) {
						allRegionList.remove(i);
						findFlag = true;
					}
				}
				count++;
			}
			if(!findFlag) {
				break;
			}
		}
		Collections.sort(allRegionList, new Comparator<WordRegionList>() {

			@Override
			public int compare(WordRegionList arg0, WordRegionList arg1) {
				return ((arg0.getFirst().getBottomY() + arg0.getLast().getBottomY()) / 2) - 
						((arg1.getFirst().getBottomY() + arg1.getLast().getBottomY()) / 2);
			}
			
		});
		count = 0;
		for(int i = allRegionList.size() - 1; i >= 0; i--) {
			WordRegionList wordRegionList = allRegionList.get(i);
			int leftX = wordRegionList.getFirst().getLeftX();
			int rightX = wordRegionList.getLast().getRightX();
			int middleX = (leftX + rightX) / 2;
			int regionWidth = rightX - leftX;
			int minY = wordRegionList.getMinY();
			int maxY = wordRegionList.getMaxY();
//			if(count == 0) {
//				System.out.println("leftX="+leftX);
//				System.out.println("rightX="+rightX);
//				System.out.println("middleX="+middleX);
//				System.out.println("regionWidth="+regionWidth);
//				System.out.println("width="+width);
//				System.out.println("ps="+(Math.abs(middleX - width/2)));
//				System.out.println("regionWidth/4="+(regionWidth/4));
//				System.out.println("minY="+minY);
//				System.out.println("maxY="+maxY);
//			}
			if(count == 0 && Math.abs(middleX - width/2) > regionWidth/4) {
				if(minY > height*2/3 && maxY > height*14/15) {
					continue;
				}
			}
			if(count == 0) {
				returnList.add(wordRegionList);
			}
			else {
				// int middleY = (wordRegionList.getFirst().getMiddleY() + wordRegionList.getLast().getMiddleY() / 2);
				if(count < 8) {
					wordRegionList.addAllLast(returnList.get(returnList.size() - 1));
					returnList.add(wordRegionList);
				}
			}
			count++;
		}
		return returnList;
	}

	private static boolean judgetAddList(WordRegionList wordRegionList1, WordRegionList wordRegionList2) {
		boolean flag = false;
		if(sameLine(wordRegionList1.getLast(), wordRegionList2.getFirst())){
			if(wordRegionList2.getFirst().getLeftX() > wordRegionList1.getLast().getMiddleX()) {
				flag = true;
				wordRegionList1.addAllLast(wordRegionList2);
				return flag;
			}
		}
		if(sameLine(wordRegionList1.getFirst(), wordRegionList2.getLast())){
			if(wordRegionList2.getLast().getRightX() < wordRegionList1.getFirst().getMiddleX()) {
				flag = true;
				wordRegionList1.addAllFirst(wordRegionList2);
				return flag;
			}
		}
		return flag;
	}

	
	private static boolean judgetAdd(WordRegionList regionList, WordRegion wordRegion) {
		boolean flag = false;
		WordRegion lastRegion = regionList.getLast();
		if(sameLine(lastRegion, wordRegion)){
			if(wordRegion.getLeftX() > lastRegion.getMiddleX()) {
				regionList.addWordRegionLast(wordRegion);
				flag = true;
				return flag;
			}
		}
		WordRegion firstRegion = regionList.getFirst();
		if(sameLine(firstRegion, wordRegion)) {
			if(wordRegion.getRightX() < firstRegion.getMiddleX()) {
				regionList.addWordRegionFirst(wordRegion);
				flag = true;
				return flag;
			}
		}
		return flag;
	}
	
	private static boolean sameLine(WordRegion wordRegion1, WordRegion wordRegion2) {
		int joinHeight = Math.min(wordRegion1.getBottomY(), wordRegion2.getBottomY()) - Math.max(wordRegion1.getTopY(), wordRegion2.getTopY());
		if(joinHeight < 0) {
			joinHeight = 0;
		}
		return (Math.abs(wordRegion1.getMiddleY() - wordRegion2.getMiddleY()) < (wordRegion1.getWordHeight() + wordRegion2.getWordHeight()) / 4)
				|| (joinHeight >= wordRegion1.getWordHeight() * 0.6)
				|| (joinHeight >= wordRegion2.getWordHeight() * 0.6);
	}
}
